package com.yi.wood.service.impl;

import com.alibaba.fastjson.JSON;
import com.yi.wood.dao.GoodsDao;
import com.yi.wood.entity.Goods;
import com.yi.wood.service.GoodsService;
import com.yi.wood.service.constant.DeletedEnum;
import com.yi.wood.service.constant.RedisConstant;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

/**
 * Created by moyi on 2019/1/30 14:27
 *
 * @author moyi
 */
public abstract class AbstractGoodsServiceImpl implements GoodsService {

    @Resource
    protected GoodsDao goodsDao;

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public Goods addData(Goods goods) {
        goods.setDeleted(DeletedEnum.NORMAL.getStatus());
        goods.setCreateTime(new Date());

        return goodsDao.save(goods);
    }

    @Override
    public Goods updateData(Goods goods) {
        goods.setUpdateTime(new Date());
        return goodsDao.save(goods);
    }

    @Override
    public Page<Goods> page(Integer type, Integer pageNum, Integer pageSize) {
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        return goodsDao.findAll(new Specification<Goods>() {
            List<Predicate> listPre = new ArrayList<>();

            @Override
            public Predicate toPredicate(Root<Goods> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                if (!Objects.isNull(type)){
                    listPre.add(criteriaBuilder.equal(root.get("type").as(Integer.class), type));
                }
                Predicate[] pre = new Predicate[listPre.size()];
                criteriaQuery.where(listPre.toArray(pre));
                return criteriaBuilder.and(pre);
            }
        }, pageable);
    }

    @Override
    public Goods updateGoodsAmount(Goods goods, Integer amount) {
        goods.setAmount(amount);
        goods.setUpdateTime(new Date());
        return goodsDao.save(goods);
    }

    @Override
    public Goods queryById(Long id) {
        Optional<Goods> optionalGoods = goodsDao.findById(id);
        return optionalGoods.orElse(null);
    }

    @Override
    public Goods queryByIdV2(Long id, Integer count) {
        String key = RedisConstant.GOODS_CONSTANT+id;
        Object obj = redisTemplate.opsForValue().get(key);
        if (obj == null){
            Goods goods = queryById(id);
            redisTemplate.opsForValue().set(key,JSON.toJSONString(goods));
            return goods;
        }
        String objStr = (String)obj;
        return JSON.parseObject(objStr, Goods.class);
    }

    @Override
    public void delData(Long id) {

    }

    @Override
    public Page<Goods> pageDataList(Example<Goods> example, Pageable pageable) {
        return null;
    }
}
